How to tile windows in Smart Office

Here is a solution to tile M3 programs in Smart Office. It is a Tiling window manager for Smart Office with automatic scaling, placement, and arrangement of windows, for example to organize M3 programs horizontally across the screen.

This solution is useful for example to put side by side two programs that a user might often use, for example Customer Order. Open Toolbox – OIS300 to see all the orders in M3, and Batch Customer Order. Open – OIS275 to see problems with those orders. A user might want to put the two windows side by side to monitor the orders. If a user does that every day, she might want a solution to tile the programs automatically. This solution will enhance the user experience and will contribute to increase user productivity.

First, we get a reference to the window with:

var window = controller.Host.Implementation; // Mango.UI.Services.EmbeddedHostWindow

Then, we de-iconify the window with:

window.ActivateWindow(true);

Then, we scale the window in pixels, for example:

window.Width = 1280;
window.Height = 800;

Then, we scale the window relative to the main Smart Office window – which is given by controller.ParentWindow – for example to half the width and full height of the screen:

window.Width = controller.ParentWindow.Width / 2;
window.Height = controller.ParentWindow.Height;

Then, we position the window horizontally and vertically in pixels on the screen by using Mango.UI.Services.DashboardService, for example:

DashboardService.Window.SetPosition(new Point(100, 20), window); // x, y

Then, we get a list of the M3 programs that are currently running – we use MainController for that – and we get a reference to each window:

var instances = MainController.Current.GetInstances(); // System.Collections.Generic.IList<IInstanceController>
for (var i: int = 0; i < instances.Count; i++) {
    var controller_: Object = instances[i]; // MForms.IInstanceController
    var window = controller_.Host.Implementation;
}

If we want to tile the windows horizontally, we scale each window’s width respective to the total number of windows. For example, if there are three windows on the screen, each window will occupy a third of the screen:

window.Width = controller_.ParentWindow.Width / instances.Count;
DashboardService.Window.SetPosition(new Point(window.Width * i, 0), window);

If we want to tile two specific M3 programs, we can find them by their name, and tile them accordingly. For example, here I position OIS275 to the left, and OIS300 to the right:

var name = controller_.RenderEngine.PanelHeader;
if (name.Equals('OIS275/B1')) {
    DashboardService.Window.SetPosition(new Point(0, 0), window); // left
} else if (name.Equals('OIS300/B')) {
    DashboardService.Window.SetPosition(new Point(controller_.ParentWindow.Width - window.Width, 0), window); // right
}

Here is my full source code to automatically tile all the windows horizontally:

import System.Windows;
import Mango.UI.Services;
import MForms;

package MForms.JScript {
	class TileHorizontally {
		public function Init(element: Object, args: Object, controller : Object, debug : Object) {
			var instances = MainController.Current.GetInstances(); // System.Collections.Generic.IList
			for (var i: int = 0; i < instances.Count; i++) {
				var controller_: Object = instances[i]; // MForms.IInstanceController
				var name = controller_.RenderEngine.PanelHeader; // M3 program name
				var window = controller_.Host.Implementation; // Mango.UI.Services.EmbeddedHostWindow
				window.ActivateWindow(true); // de-iconify
				window.Width = controller_.ParentWindow.Width / instances.Count; // set width to a respective fraction of the screen
				window.Height = controller_.ParentWindow.Height; // set to full height
				DashboardService.Window.SetPosition(new Point(window.Width * i, 0), window); // position
			}

		}
	}
}

Here is a screenshot of the result that shows three windows tiled horizontally. It’s just for illustration purposes as the windows look crowded with my low resolution screen; in a real scenario two windows or a bigger screen would look better.

Voilà!

If you liked this solution, I invite you to subscribe to this blog.

Also, read the follow-up to this post with Stand-alone scripts for Smart Office where I convert this Tiling Window Manager into a widget-like script.

Special thanks to Karinpb for the help.

Published by

thibaudatwork

ex- M3 Technical Consultant

10 thoughts on “How to tile windows in Smart Office”

  1. I want to create new window using jscript.net . when i used HostWindow and add ListView Control , that ListView Control doesn’t have default Lso theme , i checked mms001 program using inspector , it is open as EmbeddedHostWindow. please help me .

    my sample code is ,

    create host window —-
    —————————————————————————–
    HostWindow hostWindow = new HostWindow(true, true);
    hostWindow.Type =HostType.Default;
    ((Window)hostWindow).Owner = ApplicationServices.MainWindow;
    ———————————————————————————————————

    create new ListView

    ————————————————————————————————————-
    System.Windows.Controls.ListView lv = new System.Windows.Controls.ListView();
    lv.SetValue(Grid.RowProperty, 4);

    GridView gv = new GridView();
    GridViewColumn gvc1 = new GridViewColumn();

    gvc1.DisplayMemberBinding = new Binding(“Company”);
    gvc1.Header = “Company”;
    gv.Columns.Add(gvc1);

    GridViewColumn gvc2 = new GridViewColumn();
    gvc2.DisplayMemberBinding = new Binding(“Facili”);
    gvc2.Header = “Facili”;
    gv.Columns.Add(gvc2);

    GridViewColumn gvc3 = new GridViewColumn();
    gvc3.DisplayMemberBinding = new Binding(“Name”);
    gvc3.Header = “Last Name”;
    gv.Columns.Add(gvc3);

    lv.ItemsSource = (IEnumerable)facilities;
    lv.View = gv;

    grid.Children.Add((UIElement)lv);
    hostWindow.HostContent = (FrameworkElement)grid;
    ((Window)hostWindow).Show();

    ——————————————————————————————————————-

    Like

    1. Try this:
      listView.Style = StyleManager.StyleListView;
      listView.ItemContainerStyle = StyleManager.StyleListViewItem;
      gridView.ColumnHeaderContainerStyle = StyleManager.StyleGridViewColumnHeader;

      Like

Leave a comment